Summary
This workflow demonstrates the mitosRNAseq pipeline which identifies several types of small RNA from sequencing data from short reads of <50 nt. The following method collects sequence-based counts, sequence locations, genomic features, and annotations. The data we use is from killifish embyros anoxia experiments.
The step-by-step workflow we follow is illistrated below and a detailed method to perform small RNA seq on an academic HPC is decsribed in this document.

The following table shows the contents of the file samples.csv that contains metadata for our samples. We start with a total of 40 fastq files.
Sample Table
|
#
|
Sample
|
Condition
|
Stage
|
Input files
|
|
1
|
31_4d_t0
|
4d_t0
|
4
|
31_4d_t0.fastq.gz
|
|
2
|
32_4d_t0
|
4d_t0
|
4
|
32_4d_t0.fastq.gz
|
|
3
|
33_4d_t0
|
4d_t0
|
4
|
33_4d_t0.fastq.gz
|
|
4
|
34_4d_t0
|
4d_t0
|
4
|
34_4d_t0.fastq.gz
|
|
5
|
35_4d_4hrA
|
4d_4hrA
|
4
|
35_4d_4hrA.fastq.gz
|
|
6
|
36_4d_4hrA
|
4d_4hrA
|
4
|
36_4d_4hrA.fastq.gz
|
|
7
|
37_4d_4hrA
|
4d_4hrA
|
4
|
37_4d_4hrA.fastq.gz
|
|
8
|
38_4d_4hrA
|
4d_4hrA
|
4
|
38_4d_4hrA.fastq.gz
|
|
9
|
39_4d_24hrA
|
4d_24hrA
|
4
|
39_4d_24hrA.fastq.gz
|
|
10
|
40_4d_24hrA
|
4d_24hrA
|
4
|
40_4d_24hrA.fastq.gz
|
|
11
|
41_4d_24hrA
|
4d_24hrA
|
4
|
41_4d_24hrA.fastq.gz
|
|
12
|
42_4d_24hrA
|
4d_24hrA
|
4
|
42_4d_24hrA.fastq.gz
|
|
13
|
43_4d_2hrR
|
4d_2hrR
|
4
|
43_4d_2hrR.fastq.gz
|
|
14
|
44_4d_2hrR
|
4d_2hrR
|
4
|
44_4d_2hrR.fastq.gz
|
|
15
|
45_4d_2hrR
|
4d_2hrR
|
4
|
45_4d_2hrR.fastq.gz
|
|
16
|
46_4d_2hrR
|
4d_2hrR
|
4
|
46_4d_2hrR.fastq.gz
|
|
17
|
47_4d_24hrR
|
4d_24hrR
|
4
|
47_4d_24hrR.fastq.gz
|
|
18
|
48_4d_24hrR
|
4d_24hrR
|
4
|
48_4d_24hrR.fastq.gz
|
|
19
|
49_4d_24hrR
|
4d_24hrR
|
4
|
49_4d_24hrR.fastq.gz
|
|
20
|
50_4d_24hrR
|
4d_24hrR
|
4
|
50_4d_24hrR.fastq.gz
|
|
21
|
1_12d_t0
|
12d_t0
|
12
|
1_12d_t0.fastq.gz
|
|
22
|
2_12d_t0
|
12d_t0
|
12
|
2_12d_t0.fastq.gz
|
|
23
|
5_12d_t0
|
12d_t0
|
12
|
5_12d_t0.fastq.gz
|
|
24
|
6_12d_t0
|
12d_t0
|
12
|
6_12d_t0.fastq.gz
|
|
25
|
10_12d_4hrA
|
12d_4hrA
|
12
|
10_12d_4hrA.fastq.gz
|
|
26
|
11_12d_4hrA
|
12d_4hrA
|
12
|
11_12d_4hrA.fastq.gz
|
|
27
|
12_12d_4hrA
|
12d_4hrA
|
12
|
12_12d_4hrA.fastq.gz
|
|
28
|
7_12d_4hrA
|
12d_4hrA
|
12
|
7_12d_4hrA.fastq.gz
|
|
29
|
13_12d_24hrA
|
12d_24hrA
|
12
|
13_12d_24hrA.fastq.gz
|
|
30
|
16_12d_24hrA
|
12d_24hrA
|
12
|
16_12d_24hrA.fastq.gz
|
|
31
|
17_12d_24hrA
|
12d_24hrA
|
12
|
17_12d_24hrA.fastq.gz
|
|
32
|
18_12d_24hrA
|
12d_24hrA
|
12
|
18_12d_24hrA.fastq.gz
|
|
33
|
19_12d_2hrR
|
12d_2hrR
|
12
|
19_12d_2hrR.fastq.gz
|
|
34
|
21_12d_2hrR
|
12d_2hrR
|
12
|
21_12d_2hrR.fastq.gz
|
|
35
|
22_12d_2hrR
|
12d_2hrR
|
12
|
22_12d_2hrR.fastq.gz
|
|
36
|
23_12d_2hrR
|
12d_2hrR
|
12
|
23_12d_2hrR.fastq.gz
|
|
37
|
25_12d_24hrR
|
12d_24hrR
|
12
|
25_12d_24hrR.fastq.gz
|
|
38
|
28_12d_24hrR
|
12d_24hrR
|
12
|
28_12d_24hrR.fastq.gz
|
|
39
|
29_12d_24hrR
|
12d_24hrR
|
12
|
29_12d_24hrR.fastq.gz
|
|
40
|
30_12d_24hrR
|
12d_24hrR
|
12
|
30_12d_24hrR.fastq.gz
|
QC for raw reads
Quality Control (QC) is done by running fastQC on raw reads to evaluate how good (or bad) our data looks.
Install software for Quality Check
conda
Set up a virtual environment in conda that has all of the Quality Control (QC) tools. We are using Miniconda. For creating sharable environments, create .yaml files for each environment you’re making.
conda create -n condafastqc fastqc
conda activate condafastqc
conda install -n multiqc
tmux
For almost every long-ish process, we use tmux to run tasks in a detached terminal window that can keep running if we want to log out or if we accidently log out.
tmux new -s fastqc
Executing
Creating a new file called fastqcr.R that has the script to run fastqc through R. We use this script to automate the process for a list of files in a directory. Running commands through various scripts also keeps a record of our commands.
if (!require("fastqcr")) {
install.packages("fastqcr", repos="http://cran.us.r-project.org")
library(fastqcr)
} else {library(fastqcr)}
fastqc(fq.dir="/path/to/directory/init_fastq_files",
qc.dir="/path/to/directory/fastqc/init_fastqc",
threads=20)
Running the script with the following command:
Rscript fastqcr.R
Press Ctrl+B and then D for detaching this tmux window. You can log out from your remote computer (HPC) and close your terminal window now while this process keeps running on your remote computer. To get back to this window, log in to your remote computer, and use the command tmux a -t fastqc. F or more information, check tmux.
We will get a fastqc HTML file in the output fastqc directory for each fastq sequence in the input init_fastq_files directory.
FastQC Output
General Statistics from multiqc
| Sample |
PercentDups |
PercentGC |
BPMedianReadLength |
MillionsSeqs |
| 10_12d_4hrA |
94.1 |
51 |
36 |
12.6 |
| 11_12d_4hrA |
92.7 |
51 |
36 |
16.2 |
| 12_12d_4hrA |
87.4 |
52 |
36 |
9.0 |
| 13_12d_24hrA |
90.5 |
53 |
36 |
8.5 |
| 16_12d_24hrA |
91.1 |
50 |
36 |
7.9 |
| 17_12d_24hrA |
92.4 |
50 |
36 |
29.9 |
| 18_12d_24hrA |
84.6 |
52 |
36 |
11.8 |
| 19_12d_2hrR |
87.6 |
52 |
36 |
11.6 |
| 1_12d_t0 |
86.4 |
51 |
36 |
8.7 |
| 21_12d_2hrR |
95.4 |
54 |
36 |
9.8 |
| 22_12d_2hrR |
80.5 |
52 |
36 |
6.7 |
| 23_12d_2hrR |
89.3 |
52 |
36 |
7.8 |
| 25_12d_24hrR |
88.1 |
53 |
36 |
13.5 |
| 28_12d_24hrR |
91.1 |
55 |
36 |
5.9 |
| 29_12d_24hrR |
91.4 |
54 |
36 |
8.3 |
| 2_12d_t0 |
91.5 |
54 |
36 |
8.3 |
| 30_12d_24hrR |
79.9 |
53 |
36 |
12.8 |
| 31_4d_t0 |
79.3 |
52 |
50 |
11.9 |
| 32_4d_t0 |
80.1 |
53 |
50 |
11.6 |
| 33_4d_t0 |
86.3 |
51 |
50 |
13.7 |
| 34_4d_t0 |
82.9 |
52 |
50 |
15.2 |
| 35_4d_4hrA |
88.4 |
52 |
50 |
11.0 |
| 36_4d_4hrA |
87.0 |
51 |
50 |
13.8 |
| 37_4d_4hrA |
84.7 |
52 |
50 |
15.6 |
| 38_4d_4hrA |
84.4 |
51 |
50 |
15.3 |
| 39_4d_24hrA |
79.7 |
53 |
50 |
12.4 |
| 40_4d_24hrA |
74.4 |
51 |
50 |
12.9 |
| 41_4d_24hrA |
79.3 |
52 |
50 |
9.7 |
| 42_4d_24hrA |
85.6 |
53 |
50 |
16.7 |
| 43_4d_2hrR |
88.3 |
52 |
50 |
13.0 |
| 44_4d_2hrR |
81.5 |
44 |
101 |
11.0 |
| 45_4d_2hrR |
87.9 |
44 |
101 |
13.8 |
| 46_4d_2hrR |
88.9 |
52 |
50 |
16.9 |
| 47_4d_24hrR |
72.8 |
45 |
101 |
14.6 |
| 48_4d_24hrR |
83.2 |
53 |
50 |
13.4 |
| 49_4d_24hrR |
87.1 |
51 |
50 |
22.8 |
| 50_4d_24hrR |
88.9 |
41 |
101 |
14.8 |
| 5_12d_t0 |
81.3 |
53 |
36 |
11.2 |
| 6_12d_t0 |
81.7 |
53 |
36 |
13.6 |
| 7_12d_4hrA |
81.4 |
52 |
36 |
10.5 |
Sequence Counts for each sample
The mean quality scores per base in the read
The average quality scores per sequence
The GC content per sequence
Sequence Duplication
Overrepresented sequences
Adapter Content
Overall Pass/Fail
Sequence length distribution
All samples had sequences of a single length (50bp , 36bp , 101bp).
Trimming
Trimming is done with Trimmomatic in our case, however, other tools like cutadapt or fastp may also be used. This tool runs through the following bash script
FILES="/disk/bioscratch/Podrab_lab/gazal/sRNA_gazal/copied_old_infiles/init_fastq_files/*.fastq.gz"
for f in $FILES
do
b=`basename $f`
echo Running trimming for the file $b
c=${b::-9}
o="$c.trim.fastq"
log="$c.out.log"
c="$c.log.txt"
java -jar /disk/bioscratch/Podrab_lab/gazal/sRNA_gazal/trim/Trimmomatic-0.39/trimmomatic-0.39.jar SE -threads 20 -phred33 -trimlog $c $f $o ILLUMINACLIP:/disk/bioscratch/Podrab_lab/gazal/sRNA_gazal/copied_old_infiles/adapter_contamination_sequences_AR3.txt:2:30:5:1:true SLIDINGWINDOW:5:15 LEADING:20 TRAILING:20 MINLEN:15 2> $log
done
| Sample |
TotalReads |
SurvivingReads |
PercentSurviving |
DroppedReads |
PercentDropped |
| 10_12d_4hrA |
12625447 |
4421375 |
35.0 |
8204072 |
65.0 |
| 11_12d_4hrA |
16238016 |
8893201 |
54.8 |
7344815 |
45.2 |
| 12_12d_4hrA |
9024387 |
7219072 |
80.0 |
1805315 |
20.0 |
| 13_12d_24hrA |
8467459 |
5182199 |
61.2 |
3285260 |
38.8 |
| 16_12d_24hrA |
7908381 |
6458185 |
81.7 |
1450196 |
18.3 |
| 17_12d_24hrA |
29872147 |
17868683 |
59.8 |
12003464 |
40.2 |
| 18_12d_24hrA |
11793810 |
8182929 |
69.4 |
3610881 |
30.6 |
| 19_12d_2hrR |
11606761 |
9574385 |
82.5 |
2032376 |
17.5 |
| 1_12d_t0 |
8698124 |
6498924 |
74.7 |
2199200 |
25.3 |
| 21_12d_2hrR |
9784686 |
3585294 |
36.6 |
6199392 |
63.4 |
| 22_12d_2hrR |
6741253 |
4728213 |
70.1 |
2013040 |
29.9 |
| 23_12d_2hrR |
7836111 |
4455897 |
56.9 |
3380214 |
43.1 |
| 25_12d_24hrR |
13534542 |
8957294 |
66.2 |
4577248 |
33.8 |
| 28_12d_24hrR |
5866632 |
2402889 |
41.0 |
3463743 |
59.0 |
| 29_12d_24hrR |
8305061 |
2923930 |
35.2 |
5381131 |
64.8 |
| 2_12d_t0 |
8344087 |
6946381 |
83.2 |
1397706 |
16.8 |
| 30_12d_24hrR |
12811149 |
8785705 |
68.6 |
4025444 |
31.4 |
| 31_4d_t0 |
11936271 |
10306761 |
86.3 |
1629510 |
13.7 |
| 32_4d_t0 |
11595360 |
7974434 |
68.8 |
3620926 |
31.2 |
| 33_4d_t0 |
13655749 |
10422782 |
76.3 |
3232967 |
23.7 |
| 34_4d_t0 |
15201813 |
11186661 |
73.6 |
4015152 |
26.4 |
| 35_4d_4hrA |
11045591 |
7821501 |
70.8 |
3224090 |
29.2 |
| 36_4d_4hrA |
13840101 |
9383343 |
67.8 |
4456758 |
32.2 |
| 37_4d_4hrA |
15579833 |
12373672 |
79.4 |
3206161 |
20.6 |
| 38_4d_4hrA |
15286687 |
12142640 |
79.4 |
3144047 |
20.6 |
| 39_4d_24hrA |
12442304 |
9755623 |
78.4 |
2686681 |
21.6 |
| 40_4d_24hrA |
12866355 |
11130799 |
86.5 |
1735556 |
13.5 |
| 41_4d_24hrA |
9720710 |
8032689 |
82.6 |
1688021 |
17.4 |
| 42_4d_24hrA |
16698310 |
12979297 |
77.7 |
3719013 |
22.3 |
| 43_4d_2hrR |
12989273 |
9158318 |
70.5 |
3830955 |
29.5 |
| 44_4d_2hrR |
10968948 |
8421811 |
76.8 |
2547137 |
23.2 |
| 45_4d_2hrR |
13812376 |
6527219 |
47.3 |
7285157 |
52.7 |
| 46_4d_2hrR |
16946884 |
12011097 |
70.9 |
4935787 |
29.1 |
| 47_4d_24hrR |
14627707 |
12933658 |
88.4 |
1694049 |
11.6 |
| 48_4d_24hrR |
13383720 |
10269804 |
76.7 |
3113916 |
23.3 |
| 49_4d_24hrR |
22803428 |
18172334 |
79.7 |
4631094 |
20.3 |
| 50_4d_24hrR |
14759393 |
7495120 |
50.8 |
7264273 |
49.2 |
| 5_12d_t0 |
11217968 |
7594023 |
67.7 |
3623945 |
32.3 |
| 6_12d_t0 |
13607922 |
9592402 |
70.5 |
4015520 |
29.5 |
| 7_12d_4hrA |
10489257 |
6515199 |
62.1 |
3974058 |
37.9 |
QC for trimmed reads
Quality Control (QC) is done for the trimmed reads with fastQC. We activate the conda environment condafastqc for this process.
if (!require("fastqcr")) {
install.packages("fastqcr", repos="http://cran.us.r-project.org")
library(fastqcr)
} else {library(fastqcr)}
fastqc(fq.dir="/path/to/directory/trimmed_fastq_files",
qc.dir="/path/to/directory/fastqc/trim_fastqc",
threads=20)
Running the script with the following command:
Rscript fastqcr.R
FastQC Output
Plots for each FASTQC metric after trimming is shown below. All the adapters were removed and overall quality looks better.
General Statistics from multiqc
| Sample |
PercentDups |
PercentGC |
BPMedianReadLength |
MillionsSeqs |
| 10_12d_4hrA |
89.4 |
50 |
22 |
4.4 |
| 11_12d_4hrA |
90.3 |
49 |
22 |
8.9 |
| 12_12d_4hrA |
88.7 |
51 |
22 |
7.2 |
| 13_12d_24hrA |
88.4 |
50 |
22 |
5.2 |
| 16_12d_24hrA |
91.9 |
48 |
22 |
6.5 |
| 17_12d_24hrA |
91.2 |
48 |
22 |
17.9 |
| 18_12d_24hrA |
84.9 |
50 |
22 |
8.2 |
| 19_12d_2hrR |
88.5 |
51 |
22 |
9.6 |
| 1_12d_t0 |
86.7 |
49 |
22 |
6.5 |
| 21_12d_2hrR |
90.5 |
47 |
22 |
3.6 |
| 22_12d_2hrR |
80.9 |
50 |
22 |
4.7 |
| 23_12d_2hrR |
86.9 |
49 |
22 |
4.5 |
| 25_12d_24hrR |
86.6 |
50 |
22 |
9.0 |
| 28_12d_24hrR |
84.3 |
50 |
22 |
2.4 |
| 29_12d_24hrR |
83.9 |
50 |
22 |
2.9 |
| 2_12d_t0 |
93.8 |
53 |
22 |
6.9 |
| 30_12d_24hrR |
78.7 |
51 |
22 |
8.8 |
| 31_4d_t0 |
80.8 |
49 |
22 |
10.3 |
| 32_4d_t0 |
77.1 |
50 |
22 |
8.0 |
| 33_4d_t0 |
86.5 |
48 |
22 |
10.4 |
| 34_4d_t0 |
81.7 |
51 |
22 |
11.2 |
| 35_4d_4hrA |
86.5 |
50 |
22 |
7.8 |
| 36_4d_4hrA |
82.7 |
49 |
22 |
9.4 |
| 37_4d_4hrA |
84.8 |
51 |
22 |
12.4 |
| 38_4d_4hrA |
84.2 |
48 |
22 |
12.1 |
| 39_4d_24hrA |
79.1 |
51 |
23 |
9.8 |
| 40_4d_24hrA |
73.6 |
50 |
27 |
11.1 |
| 41_4d_24hrA |
79.0 |
49 |
22 |
8.0 |
| 42_4d_24hrA |
85.3 |
50 |
22 |
13.0 |
| 43_4d_2hrR |
86.9 |
50 |
22 |
9.2 |
| 44_4d_2hrR |
82.1 |
50 |
20 |
8.4 |
| 45_4d_2hrR |
80.0 |
50 |
20 |
6.5 |
| 46_4d_2hrR |
88.4 |
48 |
22 |
12.0 |
| 47_4d_24hrR |
73.3 |
48 |
26 |
12.9 |
| 48_4d_24hrR |
82.6 |
52 |
22 |
10.3 |
| 49_4d_24hrR |
87.9 |
49 |
22 |
18.2 |
| 50_4d_24hrR |
84.4 |
49 |
20 |
7.5 |
| 5_12d_t0 |
81.2 |
50 |
22 |
7.6 |
| 6_12d_t0 |
82.7 |
51 |
22 |
9.6 |
| 7_12d_4hrA |
79.5 |
50 |
22 |
6.5 |
Sequence Counts for each sample
The mean quality scores per base in the read
The average quality scores per sequence
The GC content per sequence
Sequence Duplication
Overrepresented sequences
Overall Pass/Fail
Sequence length distribution
Alignment
First things first- create a conda environment that has bowtie, samtools, picard, and bedtools.
conda create -n condabowtie bowtie samtools picard bedtools
The trimmed reads are aligned to the reference genome using bowtie. To analyze reads mapping with mitochondrial genome, we perform the alignment in two steps.
- Complete Genome (with mitochondrial genome)- with algenome.fa
- Only the Mitochondrial genome which is extracted from genome.fa- almitogenome.fa
To begin alignment, we make bowtie indexes, this is done in two sets.
bowtie-index algenome.fa
bowtie-index almitogenome.fa
Alignment with genome
The alignment was done on the trimmed reads from previous section.
#!/bin/bash
FILES="/disk/bioscratch/Podrab_lab/gazal/sRNA_gazal/trim/*.fastq"
for f in $FILES
do
b=`basename $f`
echo Running trimming for the file $b
t=${b::-6}
o="$t.sam"
uo="$t.mapped.fq"
echo Output file is $o
bowtie \
-p 20 \
-t \
-k 5 \
--best \
--strata \
-e 99999 \
-v 0 \
-l 15 \
--chunkmbs 2048 \
-x /disk/bioscratch/Podrab_lab/gazal/sRNA_gazal/bowtie_index_alim/algenome \
-q $f \
--al $uo \
--sam --no-unal > $o 2> $t.bowtie.log
done
#done
The following stats show alignment QC.
This table shows the number of reads aligned in each sample (MillionAlignedReads). It also shows the number of aligments of various reads that includes multimapped reads (MillionMappedReads).
|
Sample
|
PercentAligned
|
MillionAlignedReads
|
MillionMappedReads
|
|
10_12d_4hrA
|
73.2
|
3.2
|
8.0
|
|
11_12d_4hrA
|
73.6
|
6.5
|
15.4
|
|
12_12d_4hrA
|
70.4
|
5.1
|
12.4
|
|
13_12d_24hrA
|
69.6
|
3.6
|
8.7
|
|
16_12d_24hrA
|
77.5
|
5.0
|
10.3
|
|
17_12d_24hrA
|
75.8
|
13.5
|
31.4
|
|
18_12d_24hrA
|
73.7
|
6.0
|
15.0
|
|
19_12d_2hrR
|
71.9
|
6.9
|
16.8
|
|
1_12d_t0
|
73.3
|
4.8
|
11.1
|
|
21_12d_2hrR
|
77.8
|
2.8
|
5.3
|
|
22_12d_2hrR
|
66.2
|
3.1
|
7.4
|
|
23_12d_2hrR
|
73.2
|
3.3
|
7.8
|
|
25_12d_24hrR
|
69.7
|
6.2
|
15.0
|
|
28_12d_24hrR
|
65.3
|
1.6
|
3.7
|
|
29_12d_24hrR
|
70.9
|
2.1
|
5.0
|
|
2_12d_t0
|
76.9
|
5.3
|
13.1
|
|
30_12d_24hrR
|
65.5
|
5.8
|
13.8
|
|
31_4d_t0
|
62.0
|
6.4
|
11.8
|
|
32_4d_t0
|
73.5
|
5.9
|
12.2
|
|
33_4d_t0
|
80.6
|
8.4
|
15.0
|
|
34_4d_t0
|
70.5
|
7.9
|
15.8
|
|
35_4d_4hrA
|
71.5
|
5.6
|
9.2
|
|
36_4d_4hrA
|
62.1
|
5.8
|
8.3
|
|
37_4d_4hrA
|
69.1
|
8.6
|
16.4
|
|
38_4d_4hrA
|
76.1
|
9.2
|
15.4
|
|
39_4d_24hrA
|
79.0
|
7.7
|
17.2
|
|
40_4d_24hrA
|
52.3
|
5.8
|
10.9
|
|
41_4d_24hrA
|
63.0
|
5.1
|
8.8
|
|
42_4d_24hrA
|
66.6
|
8.6
|
15.2
|
|
43_4d_2hrR
|
71.2
|
6.5
|
11.7
|
|
44_4d_2hrR
|
64.6
|
5.4
|
11.8
|
|
45_4d_2hrR
|
65.7
|
4.3
|
9.5
|
|
46_4d_2hrR
|
71.2
|
8.6
|
13.8
|
|
47_4d_24hrR
|
80.1
|
10.4
|
24.4
|
|
48_4d_24hrR
|
51.8
|
5.3
|
10.7
|
|
49_4d_24hrR
|
72.3
|
13.1
|
23.2
|
|
50_4d_24hrR
|
79.4
|
6.0
|
13.4
|
|
5_12d_t0
|
66.2
|
5.0
|
11.9
|
|
6_12d_t0
|
67.5
|
6.5
|
15.5
|
|
7_12d_4hrA
|
65.6
|
4.3
|
10.1
|
Alignment with mitochondria
The alignment was done on the trimmed reads from previous section.
The following stats show alignment QC.
#!/bin/bash
FILES="/disk/bioscratch/Podrab_lab/gazal/sRNA_gazal/trim/*.fastq"
for f in $FILES
do
b=`basename $f`
echo Running alignment for the file $b
t=${b::-6}
o="$t.sam"
uo="$t.mapped.fq"
echo Output file is $o
bowtie \
-p 20 \
-t \
-k 10 \
--best \
--strata \
-e 99999 \
-v 0 \
-l 15 \
--chunkmbs 2048 \
-x /disk/bioscratch/Podrab_lab/gazal/sRNA_gazal/bowtie_mito_index/almitogenome \
-q $f \
--al $uo \
--sam --no-unal > $o 2> $t.bowtie.log
done
#done
This table shows the number of reads aligned in each sample (MillionAlignedReads). It also shows the number of aligments of various reads that includes multimapped reads (MillionMappedReads).
|
Sample
|
PercentAligned
|
MillionAlignedReads
|
MillionMappedReads
|
|
10_12d_4hrA
|
0.34
|
0.01
|
0.02
|
|
11_12d_4hrA
|
0.47
|
0.04
|
0.04
|
|
12_12d_4hrA
|
0.41
|
0.03
|
0.03
|
|
13_12d_24hrA
|
0.50
|
0.03
|
0.03
|
|
16_12d_24hrA
|
0.52
|
0.03
|
0.03
|
|
17_12d_24hrA
|
3.25
|
0.58
|
0.59
|
|
18_12d_24hrA
|
6.22
|
0.51
|
0.52
|
|
19_12d_2hrR
|
0.92
|
0.09
|
0.09
|
|
1_12d_t0
|
1.25
|
0.08
|
0.08
|
|
21_12d_2hrR
|
0.79
|
0.03
|
0.03
|
|
22_12d_2hrR
|
4.43
|
0.21
|
0.21
|
|
23_12d_2hrR
|
2.68
|
0.12
|
0.12
|
|
25_12d_24hrR
|
4.72
|
0.42
|
0.43
|
|
28_12d_24hrR
|
0.32
|
0.01
|
0.01
|
|
29_12d_24hrR
|
4.08
|
0.12
|
0.12
|
|
2_12d_t0
|
0.25
|
0.02
|
0.02
|
|
30_12d_24hrR
|
8.18
|
0.72
|
0.73
|
|
31_4d_t0
|
4.99
|
0.51
|
0.52
|
|
32_4d_t0
|
10.12
|
0.81
|
0.82
|
|
33_4d_t0
|
1.99
|
0.21
|
0.21
|
|
34_4d_t0
|
6.72
|
0.75
|
0.77
|
|
35_4d_4hrA
|
0.43
|
0.03
|
0.03
|
|
36_4d_4hrA
|
0.59
|
0.06
|
0.06
|
|
37_4d_4hrA
|
1.10
|
0.14
|
0.14
|
|
38_4d_4hrA
|
5.67
|
0.69
|
0.70
|
|
39_4d_24hrA
|
8.32
|
0.81
|
0.83
|
|
40_4d_24hrA
|
7.77
|
0.87
|
0.88
|
|
41_4d_24hrA
|
7.50
|
0.60
|
0.61
|
|
42_4d_24hrA
|
2.13
|
0.28
|
0.28
|
|
43_4d_2hrR
|
0.61
|
0.06
|
0.06
|
|
44_4d_2hrR
|
1.00
|
0.08
|
0.09
|
|
45_4d_2hrR
|
4.69
|
0.31
|
0.31
|
|
46_4d_2hrR
|
1.07
|
0.13
|
0.13
|
|
47_4d_24hrR
|
16.68
|
2.16
|
2.19
|
|
48_4d_24hrR
|
0.18
|
0.02
|
0.02
|
|
49_4d_24hrR
|
1.49
|
0.27
|
0.28
|
|
50_4d_24hrR
|
2.22
|
0.17
|
0.17
|
|
5_12d_t0
|
6.11
|
0.46
|
0.47
|
|
6_12d_t0
|
6.47
|
0.62
|
0.63
|
|
7_12d_4hrA
|
5.39
|
0.35
|
0.36
|
Another QC that we could fo with the aligned read is with Picard. The following is the command line to do that:
FILES="/disk/bioscratch/Podrab_lab/gazal/sRNA_gazal/align_with_alim_for_anno/alim_mito_anno/*sorted.bam"
for f in $FILES
do
b=`basename $f`
echo Converting file $b
o="$b.picard.txt"
echo Output file is $o
picard -Xmx5g CollectAlignmentSummaryMetrics I=$f O=$o R=/disk/bioscratch/Podrab_lab/gazal/sRNA_gazal/copied_old_infiles/GCF_001266775.1_Austrofundulus_limnaeus-1.0_genomic_andMITO.fna
done
#done
Before we proceed, we need to sort the sam, convert it into bam and create a bam index (bai). This step ensures that we could store the alignments in acceptable binary format that takes less storage space and is compatible with subsequent steps.
FILES="/disk/bioscratch/Podrab_lab/gazal/sRNA_gazal/align_with_alim_for_anno/alim_mito_anno/*.sam"
for f in $FILES
do
b=`basename $f`
echo Converting $b to bam
o=${b::-4}
bam="$o.bam"
sortedbam="$b.sorted.bam"
echo Tmp file is $bam
samtools view -b $f > $bam
echo Output files are $sortedbam and its index
samtools sort $bam -o $sortedbam
samtools index $sortedbam
echo Deleting Tmp file $bam
rm $bam
done
#done
Using aligned reads
We will create three files:
- Summary information that has read ID, sequence, reference location, and number of alignments.
- Exact location, genomic features of the reference location that the reads mapped to via bedtools.
- Counting the readcounts from bam files.
FILES="/disk/bioscratch/Podrab_lab/gazal/sRNA_gazal/align_with_alim_for_anno/alim_mito_anno/*.bam"
for f in $FILES
do
b=`basename $f`
echo $b
o=${b::-4}
o="$o.summary.txt"
input_file="$f"
output_file="$o.summary.txt"
# Process the input file with samtools and awk
samtools view $f | awk '{print $1, $10, $3, $4, $15}' | sort | uniq > "$output_file"
echo "Output file written $output_file"
done
The result is the following data for each file. The sample 1_12d_t0 is shown. 
FILES="/disk/bioscratch/Podrab_lab/gazal/sRNA_gazal/align_with_alim_for_anno/alim_mito_anno/*.bam"
for f in $FILES
do
b=`basename $f`
echo $b
o=${b::-4}
bed="$o.bed"
out="$o.bedtools.txt"
gff="/disk/bioscratch/Podrab_lab/gazal/sRNA_gazal/mito_genome/GCF_001266775.1_Austrofundulus_limnaeus_MITOonly.gff"
bedtools intersect -a $f -b $gff -wo -f 1 -bed > $bed
awk '!seen[$4]++' $bed > tmp.csv
rm $bed
awk '{print $4, $21}' tmp.csv > $out
rm tmp.csv
echo "Output file written $out"
done
The result of above command gives us the following data for each file. The sample 1_12d_t0 is shown. 
FILES="/disk/bioscratch/Podrab_lab/gazal/sRNA_gazal/align_with_alim_for_anno/alim_mito_anno/*.bam"
for f in $FILES
do
b=`basename $f`
echo $b
o=${b::-4}
o="$o.readcount.txt"
echo Output file is $o
# Count unique occurrences of column 10
samtools view $f | awk '{print $10}'| sort | uniq -c > "$o"
echo "Output written to $o"
done
The result of above command gives us the following data for each file. The sample 1_12d_t0 is shown. 
miRTrace
Running mirtrace with the following command.
mirtrace qc --species dre --config seq_address.txt
Looking at the results:

sports
Executing sports tool on mapped reads only. We use the following command to run:
#!/bin/bash
sports.pl -i seqs_alim_mito.txt \
-o /disk/bioscratch/Podrab_lab/gazal/sRNA_gazal/align_with_alimnaeus/gen_input_fastq/SPORTS/out_sports/REDO/mito_mapped_reads \
-k \
-M 2 \
-p 20 \
-g /disk/bioscratch/Podrab_lab/gazal/sRNA_gazal/bowtie_mito_index/almitogenome \
-m /disk/bioscratch/Podrab_lab/gazal/sRNA_gazal/align_with_alimnaeus/gen_input_fastq/SPORTS/sports1.1/db/Danio_rerio/miRBase_21/miRBase_21-dre \
-r /disk/bioscratch/Podrab_lab/gazal/sRNA_gazal/align_with_alimnaeus/gen_input_fastq/SPORTS/sports1.1/db/Danio_rerio/rRNA_db/zebrafish_rRNA \
-t /disk/bioscratch/Podrab_lab/gazal/sRNA_gazal/align_with_alimnaeus/gen_input_fastq/SPORTS/sports1.1/db/Danio_rerio/GtRNAdb/danRer6-tRNAs \
-w /disk/bioscratch/Podrab_lab/gazal/sRNA_gazal/align_with_alimnaeus/gen_input_fastq/SPORTS/sports1.1/db/Danio_rerio/piRBase/piR_dre_v1.0 \
-e /disk/bioscratch/Podrab_lab/gazal/sRNA_gazal/align_with_alimnaeus/gen_input_fastq/SPORTS/sports1.1/db/Danio_rerio/Ensembl/Danio_rerio.GRCz10.ncrna \
-f /disk/bioscratch/Podrab_lab/gazal/sRNA_gazal/align_with_alimnaeus/gen_input_fastq/SPORTS/sports1.1/db/Danio_rerio/Rfam_12.3/Rfam-12.3-zebrafish
This will generate a number of output files, from which the tables generated as a result file *_output.txt for each sample are taken and are used to extract annotation of mapped reads. Top 50 rows of this table are shown for the sample 10_12d_4hrA below.

It also generates a number of plots to categorize the annotations and their length distributions for each sample.

Compiling output files
At the end, we need to compile all the output files into a single dataframe that can be exported to further do downstream processing such as statistics, differential expression, and clustering.
We provide an R script that compiles these output files:
- Annotation: From sports- *.mapped_output.txt
- Alignment summary: From .bam files with samtools- *.summary.txt
- Readcount: From .bam files with samtools and awk- *.readcount.txt
- Location: From .bam files with bedtools- *.bedtools.txt
In addition, we also need a sample design file (.csv format) that has details about the samples. This file makes it easier to do statistical analysis on the data using R packages like DESeq2, ExpressionSet, and EdgeR.
You would alter the following lines in the R script that basically tells the program where these txt files are located.
parent_dir <- "D:/PSU_work/smrnaseq/mito_map"
samples <- "D:/PSU_work/smrnaseq/mito_map/design_samples.csv"
readcount_txt_pattern <- "sorted.readcount.txt$"
output_txt_pattern <- "mapped_output.txt$"
summary_txt_pattern <- "summary.txt$"
bedtools_txt_pattern <- "bedtools.txt$"
Set pattern of filenames: these files are searched in the parent_dir recursively. Make sure that the parent_dir contains these files and the pattern should be unique to list the files that we need.
Merge results from our samples can be viewed from our github repo
Visualizing
We use the alignments with mitochondrial genome to view the aligned reads.
Jbrowse is used to explore alignments.
Files used:
- Aligned bam files for each sample and its corresponding index file (bam, bai)
- Reference genome for mitochondria (.fasta) and its index file (.fai)
- Genome feature file (.gff) for mitochondrial genome
Click to enlarge
This figure shows mitochondiral genome of 100bp length from 17100 to 17199. On this genome, we see 1) the colored basepairs, 2) Genomic features of the mentioned length, 3) Alignments from 4 samples (4d t0 replicates) that show reads aligned to the genome colored by strand while also showing the coverage histogram in grey.
LS0tCnRpdGxlOiAibWl0b3NSTkFzZXEgV29ya2Zsb3ciCmRhdGU6IDA4LTE1LTIwMjQKb3V0cHV0OiAKICAgIGh0bWxfbm90ZWJvb2s6CiAgICAgICAgdG9jOiBUUlVFCiAgICAgICAgdG9jX2Zsb2F0OiB0cnVlCi0tLQoKCiMjICBTdW1tYXJ5ClRoaXMgd29ya2Zsb3cgZGVtb25zdHJhdGVzIHRoZSBtaXRvc1JOQXNlcSBwaXBlbGluZSB3aGljaCBpZGVudGlmaWVzIHNldmVyYWwgdHlwZXMgb2YKc21hbGwgUk5BIGZyb20gc2VxdWVuY2luZyBkYXRhIGZyb20gc2hvcnQgcmVhZHMgb2YgPDUwIG50LiBUaGUgZm9sbG93aW5nIG1ldGhvZCBjb2xsZWN0cyBzZXF1ZW5jZS1iYXNlZCAKY291bnRzLCBzZXF1ZW5jZSBsb2NhdGlvbnMsIGdlbm9taWMgZmVhdHVyZXMsIGFuZCBhbm5vdGF0aW9ucy4gClRoZSBkYXRhIHdlIHVzZSBpcyBmcm9tIGtpbGxpZmlzaCBlbWJ5cm9zIGFub3hpYSBleHBlcmltZW50cy4gCgpUaGUgc3RlcC1ieS1zdGVwIHdvcmtmbG93IHdlIGZvbGxvdyBpcyBpbGxpc3RyYXRlZCBiZWxvdyBhbmQgYSAKZGV0YWlsZWQgbWV0aG9kIHRvIHBlcmZvcm0gc21hbGwgUk5BIHNlcSBvbiBhbiBhY2FkZW1pYyBIUEMgaXMgZGVjc3JpYmVkIGluIHRoaXMgZG9jdW1lbnQuIAoKIVtdKC9ob21lL2dhemFsL0RvY3VtZW50cy9QU1Vfd29yay9zUk5BX2dhemFsL2RvY3VtZW50YXRpb24vRmlndXJlIDEucG5nKQoKVGhlIGZvbGxvd2luZyB0YWJsZSBzaG93cyB0aGUgY29udGVudHMgb2YgdGhlIGZpbGUgKipzYW1wbGVzLmNzdioqIHRoYXQgY29udGFpbnMgbWV0YWRhdGEgZm9yIG91ciBzYW1wbGVzLgpXZSBzdGFydCB3aXRoIGEgdG90YWwgb2YgNDAgZmFzdHEgZmlsZXMuCgojIyMgU2FtcGxlIFRhYmxlCmBgYHtyIGVjaG89RkFMU0UsIHJlc3VsdHM9J2FzaXMnLCB3YXJuaW5nPUZBTFNFfQpsaWJyYXJ5KGtuaXRyKQpsaWJyYXJ5KHJlYWRyKQpsaWJyYXJ5KGZvcm1hdHRhYmxlKQpsaWJyYXJ5KHJlYWRyKQpkZl9zYW1wbGVzIDwtIHJlYWRfY3N2KCJzYW1wbGVzLmNzdiIsIHNob3dfY29sX3R5cGVzID0gRkFMU0UpCmZvcm1hdHRhYmxlKGRmX3NhbXBsZXMsCiAgICAgICAgdGFibGUuYXR0ciA9ICdzdHlsZSA9ICJ3aWR0aDo1MCU7IGZvbnQtc2l6ZTo5MCU7IicKICAgICAgICApCmBgYAoKIyMgUUMgZm9yIHJhdyByZWFkcwoKUXVhbGl0eSBDb250cm9sIChRQykgaXMgZG9uZSBieSBydW5uaW5nIGZhc3RRQyBvbiByYXcgcmVhZHMgdG8gZXZhbHVhdGUgaG93IGdvb2QgKG9yIGJhZCkgb3VyIGRhdGEgbG9va3MuCgojIyMgSW5zdGFsbCBzb2Z0d2FyZSBmb3IgUXVhbGl0eSBDaGVjawoKKipjb25kYSoqCgpTZXQgdXAgYSB2aXJ0dWFsIGVudmlyb25tZW50IGluIGNvbmRhIHRoYXQgaGFzIGFsbCBvZiB0aGUgUXVhbGl0eSBDb250cm9sIChRQykgdG9vbHMuIApXZSBhcmUgdXNpbmcgW01pbmljb25kYV0oaHR0cHM6Ly9kb2NzLmFuYWNvbmRhLmNvbS9taW5pY29uZGEvKS4gCkZvciBjcmVhdGluZyBzaGFyYWJsZSBlbnZpcm9ubWVudHMsIGNyZWF0ZSAueWFtbCBmaWxlcyBmb3IgZWFjaCBlbnZpcm9ubWVudCB5b3UncmUgbWFraW5nLgoKYGBgCmNvbmRhIGNyZWF0ZSAtbiBjb25kYWZhc3RxYyBmYXN0cWMKY29uZGEgYWN0aXZhdGUgY29uZGFmYXN0cWMKY29uZGEgaW5zdGFsbCAtbiBtdWx0aXFjCmBgYAoKKip0bXV4KioKCkZvciBhbG1vc3QgZXZlcnkgbG9uZy1pc2ggcHJvY2VzcywgCndlIHVzZSB0bXV4IHRvIHJ1biB0YXNrcyBpbiBhIGRldGFjaGVkIHRlcm1pbmFsIHdpbmRvdyB0aGF0IGNhbiBrZWVwIHJ1bm5pbmcgaWYgd2Ugd2FudCB0byBsb2cgb3V0IG9yIGlmIHdlIGFjY2lkZW50bHkgbG9nIG91dC4KYGBgCnRtdXggbmV3IC1zIGZhc3RxYwpgYGAKCiMjIyBFeGVjdXRpbmcKCkNyZWF0aW5nIGEgbmV3IGZpbGUgY2FsbGVkICoqZmFzdHFjci5SKiogdGhhdCBoYXMgdGhlIHNjcmlwdCB0byBydW4gZmFzdHFjIHRocm91Z2ggUi4KV2UgdXNlIHRoaXMgc2NyaXB0IHRvIGF1dG9tYXRlIHRoZSBwcm9jZXNzIGZvciBhIGxpc3Qgb2YgZmlsZXMgaW4gYSBkaXJlY3RvcnkuIApSdW5uaW5nIGNvbW1hbmRzIHRocm91Z2ggdmFyaW91cyBzY3JpcHRzIGFsc28ga2VlcHMgYSByZWNvcmQgb2Ygb3VyIGNvbW1hbmRzLgoKYGBgCmlmICghcmVxdWlyZSgiZmFzdHFjciIpKSB7CiAgICAgICAgaW5zdGFsbC5wYWNrYWdlcygiZmFzdHFjciIsIHJlcG9zPSJodHRwOi8vY3Jhbi51cy5yLXByb2plY3Qub3JnIikKICAgICAgICBsaWJyYXJ5KGZhc3RxY3IpCn0gZWxzZSB7bGlicmFyeShmYXN0cWNyKX0KZmFzdHFjKGZxLmRpcj0iL3BhdGgvdG8vZGlyZWN0b3J5L2luaXRfZmFzdHFfZmlsZXMiLAogICAgICBxYy5kaXI9Ii9wYXRoL3RvL2RpcmVjdG9yeS9mYXN0cWMvaW5pdF9mYXN0cWMiLAogICAgICB0aHJlYWRzPTIwKQpgYGAKClJ1bm5pbmcgdGhlIHNjcmlwdCB3aXRoIHRoZSBmb2xsb3dpbmcgY29tbWFuZDoKYGBgClJzY3JpcHQgZmFzdHFjci5SCmBgYApQcmVzcyBgQ3RybCtCYCBhbmQgdGhlbiBgRGAgZm9yIGRldGFjaGluZyB0aGlzIHRtdXggd2luZG93LiAKWW91IGNhbiBsb2cgb3V0IGZyb20geW91ciByZW1vdGUgY29tcHV0ZXIgKEhQQykgYW5kIGNsb3NlIHlvdXIgdGVybWluYWwgCndpbmRvdyBub3cgd2hpbGUgdGhpcyBwcm9jZXNzIGtlZXBzIHJ1bm5pbmcgb24geW91ciByZW1vdGUgY29tcHV0ZXIuIApUbyBnZXQgYmFjayB0byB0aGlzIHdpbmRvdywgbG9nIGluIHRvIHlvdXIgcmVtb3RlIGNvbXB1dGVyLCBhbmQKIHVzZSB0aGUgY29tbWFuZCBgdG11eCBhIC10IGZhc3RxY2AuIEYKb3IgbW9yZSBpbmZvcm1hdGlvbiwgY2hlY2sgW3RtdXhdKGh0dHBzOi8vZ2l0aHViLmNvbS90bXV4L3RtdXgvd2lraS9HZXR0aW5nLVN0YXJ0ZWQpLiAKCldlIHdpbGwgZ2V0IGEgZmFzdHFjIEhUTUwgZmlsZSBpbiB0aGUgb3V0cHV0IGZhc3RxYyBkaXJlY3RvcnkgZm9yIAplYWNoIGZhc3RxIHNlcXVlbmNlIGluIHRoZSBpbnB1dCBpbml0X2Zhc3RxX2ZpbGVzIGRpcmVjdG9yeS4KCiMjIyBGYXN0UUMgT3V0cHV0CgoqKkdlbmVyYWwgU3RhdGlzdGljcyBmcm9tIG11bHRpcWMqKgpgYGB7ciBlY2hvPUZBTFNFLCByZXN1bHRzPSdhc2lzJywgd2FybmluZz1GQUxTRX0KbGlicmFyeShyZWFkcikKbGlicmFyeShmb3JtYXR0YWJsZSkKZGZfc3RhdHMgPC0gcmVhZF90c3YoIm11bHRpcWNfaW5pdF9mYXN0cS9nZW5lcmFsX3N0YXRzX3RhYmxlLnRzdiIsIHNob3dfY29sX3R5cGVzID0gRkFMU0UpCmlzLm51bSA8LSBzYXBwbHkoZGZfc3RhdHMsIGlzLm51bWVyaWMpCmRmX3N0YXRzW2lzLm51bV0gPC0gbGFwcGx5KGRmX3N0YXRzW2lzLm51bV0sIHJvdW5kLCAxKQpmb3JtYXR0YWJsZShkZl9zdGF0cywgbGlzdCgKICAgICdQZXJjZW50RHVwcycgPSBjb2xvcl9iYXIoIiNFOTk2N0EiKSwKICAgICdQZXJjZW50R0MnID0gY29sb3JfYmFyKCIjREFBNTIwIiksCiAgICAnQlBNZWRpYW5SZWFkTGVuZ3RoJyA9IGNvbG9yX2JhcigiIzY2Q0RBQSIpLAogICAgJ01pbGxpb25zU2VxcycgPSBjb2xvcl9iYXIoIiNEQTcwRDYiKSksCiAgICB0YWJsZS5hdHRyID0gImNsYXNzPVwndGFibGUgdGFibGUtY29uZGVuc2VkXCcsIHN0eWxlPVwnd2lkdGg6ODAlOyBmb250LXNpemU6OTAlO1wnIgopCmBgYAoKKipTZXF1ZW5jZSBDb3VudHMgZm9yIGVhY2ggc2FtcGxlKioKCiFbU2VxdWVuY2UgQ291bnRzXShtdWx0aXFjX2luaXRfZmFzdHEvbXVsdGlxY19wbG90cy9mYXN0cWNfc2VxdWVuY2VfY291bnRzX3Bsb3QucG5nKXt3aWR0aD01NTBweH0KCioqVGhlIG1lYW4gcXVhbGl0eSBzY29yZXMgcGVyIGJhc2UgaW4gdGhlIHJlYWQqKgoKIVtQZXIgQmFzZSBRdWFsaXR5XShtdWx0aXFjX2luaXRfZmFzdHEvbXVsdGlxY19wbG90cy9mYXN0cWNfcGVyX2Jhc2Vfc2VxdWVuY2VfcXVhbGl0eV9wbG90LnBuZyl7d2lkdGg9NTUwcHh9CgoqKlRoZSBhdmVyYWdlIHF1YWxpdHkgc2NvcmVzIHBlciBzZXF1ZW5jZSoqCgohW1BlciBTZXF1ZW5jZSBRdWFsaXR5XShtdWx0aXFjX2luaXRfZmFzdHEvbXVsdGlxY19wbG90cy9mYXN0cWNfcGVyX3NlcXVlbmNlX3F1YWxpdHlfc2NvcmVzX3Bsb3QucG5nKXt3aWR0aD01NTBweH0KCioqVGhlIEdDIGNvbnRlbnQgcGVyIHNlcXVlbmNlKioKCiFbR0MgY29uZXRlbnRdKG11bHRpcWNfaW5pdF9mYXN0cS9tdWx0aXFjX3Bsb3RzL2Zhc3RxY19wZXJfc2VxdWVuY2VfZ2NfY29udGVudF9wbG90LnBuZyl7d2lkdGg9NTUwcHh9CgoKKipTZXF1ZW5jZSBEdXBsaWNhdGlvbioqCgohW0R1cGxpY2F0aW9uIGluIGVhY2ggc2VxdWVuY2VdKG11bHRpcWNfaW5pdF9mYXN0cS9tdWx0aXFjX3Bsb3RzL2Zhc3RxY19zZXF1ZW5jZV9kdXBsaWNhdGlvbl9sZXZlbHNfcGxvdC5wbmcpe3dpZHRoPTU1MHB4fQoKKipPdmVycmVwcmVzZW50ZWQgc2VxdWVuY2VzKioKCiFbVG90YWwgb3ZlcnJlcHJlc2VudGVkIHNlcXVlbmNlcyBmb3VuZCBpbiBlYWNoIHNhbXBsZV0obXVsdGlxY19pbml0X2Zhc3RxL211bHRpcWNfcGxvdHMvZmFzdHFjX292ZXJyZXByZXNlbnRlZF9zZXF1ZW5jZXNfcGxvdC5wbmcpe3dpZHRoPTU1MHB4fQoKKipBZGFwdGVyIENvbnRlbnQqKgoKIVtBZGFwdGVycyBmb3VuZCBhdCBzZXF1ZW5jZSBwb3NpdGlvbnNdKG11bHRpcWNfaW5pdF9mYXN0cS9tdWx0aXFjX3Bsb3RzL2Zhc3RxY19hZGFwdGVyX2NvbnRlbnRfcGxvdC5wbmcpe3dpZHRoPTU1MHB4fQoKKipPdmVyYWxsIFBhc3MvRmFpbCoqCgohW0NoZWNraW5nIGlmIGVhY2ggc2FtcGxlIHBhc3NlcyBvciBmYWlscyBpbiB2YXJpb3VzIG1ldGVyaXNdKG11bHRpcWNfaW5pdF9mYXN0cS9tdWx0aXFjX3Bsb3RzL2Zhc3RxYy1zdGF0dXMtY2hlY2staGVhdG1hcC5wbmcpe3dpZHRoPTU1MHB4fQoKKipTZXF1ZW5jZSBsZW5ndGggZGlzdHJpYnV0aW9uKioKCkFsbCBzYW1wbGVzIGhhZCBzZXF1ZW5jZXMgb2YgYSBzaW5nbGUgbGVuZ3RoICg1MGJwICwgMzZicCAsIDEwMWJwKS4KCiMjIFRyaW1taW5nCgpUcmltbWluZyBpcyBkb25lIHdpdGggVHJpbW1vbWF0aWMgaW4gb3VyIGNhc2UsIGhvd2V2ZXIsIG90aGVyIHRvb2xzIGxpa2UgY3V0YWRhcHQgb3IgZmFzdHAgbWF5IGFsc28gYmUgdXNlZC4KVGhpcyB0b29sIHJ1bnMgdGhyb3VnaCB0aGUgZm9sbG93aW5nIGJhc2ggc2NyaXB0CgpgYGAKRklMRVM9Ii9kaXNrL2Jpb3NjcmF0Y2gvUG9kcmFiX2xhYi9nYXphbC9zUk5BX2dhemFsL2NvcGllZF9vbGRfaW5maWxlcy9pbml0X2Zhc3RxX2ZpbGVzLyouZmFzdHEuZ3oiCmZvciBmIGluICRGSUxFUwogICAgZG8KICAgICAgICBiPWBiYXNlbmFtZSAkZmAKICAgICAgICBlY2hvIFJ1bm5pbmcgdHJpbW1pbmcgZm9yIHRoZSBmaWxlICRiCgogICAgICAgIGM9JHtiOjotOX0KICAgICAgICBvPSIkYy50cmltLmZhc3RxIgoJbG9nPSIkYy5vdXQubG9nIgogICAgICAgIGM9IiRjLmxvZy50eHQiCiAgICAgICAgamF2YSAtamFyIC9kaXNrL2Jpb3NjcmF0Y2gvUG9kcmFiX2xhYi9nYXphbC9zUk5BX2dhemFsL3RyaW0vVHJpbW1vbWF0aWMtMC4zOS90cmltbW9tYXRpYy0wLjM5LmphciBTRSAtdGhyZWFkcyAyMCAtcGhyZWQzMyAtdHJpbWxvZyAkYyAkZiAkbyBJTExVTUlOQUNMSVA6L2Rpc2svYmlvc2NyYXRjaC9Qb2RyYWJfbGFiL2dhemFsL3NSTkFfZ2F6YWwvY29waWVkX29sZF9pbmZpbGVzL2FkYXB0ZXJfY29udGFtaW5hdGlvbl9zZXF1ZW5jZXNfQVIzLnR4dDoyOjMwOjU6MTp0cnVlIFNMSURJTkdXSU5ET1c6NToxNSBMRUFESU5HOjIwIFRSQUlMSU5HOjIwIE1JTkxFTjoxNSAyPiAkbG9nCiAgICBkb25lCmBgYAoKIVtSZWFkcyBTdXJ2aXZpbmddKHRyaW1tb21hdGljL3RyaW1tb21hdGljX3Bsb3QucG5nKXt3aWR0aD01NTBweH0KCmBgYHtyIGVjaG89RkFMU0UsIHJlc3VsdHM9J2FzaXMnLCB3YXJuaW5nPUZBTFNFfQpsaWJyYXJ5KHJlYWRyKQpsaWJyYXJ5KGZvcm1hdHRhYmxlKQpkZl9zdGF0cyA8LSByZWFkX3RzdigidHJpbW1vbWF0aWMvdHJpbW1vbWF0aWNfcGxvdC50c3YiLCBzaG93X2NvbF90eXBlcyA9IEZBTFNFKQppcy5udW0gPC0gc2FwcGx5KGRmX3N0YXRzLCBpcy5udW1lcmljKQpkZl9zdGF0c1tpcy5udW1dIDwtIGxhcHBseShkZl9zdGF0c1tpcy5udW1dLCByb3VuZCwgMSkKZm9ybWF0dGFibGUoZGZfc3RhdHMsIGxpc3QoCiAgICAnVG90YWxSZWFkcycgPSBjb2xvcl9iYXIoIiNCREI3NkIiKSwKICAgICdTdXJ2aXZpbmdSZWFkcycgPSBjb2xvcl9iYXIoIiM5MEVFOTAiKSwKICAgICdQZXJjZW50U3Vydml2aW5nJyA9IGNvbG9yX2JhcigiIzMyQ0QzMiIpLAogICAgJ0Ryb3BwZWRSZWFkcycgPSBjb2xvcl9iYXIoIiNGMDgwODAiKSwKICAgICdQZXJjZW50RHJvcHBlZCcgPSBjb2xvcl9iYXIoIiNDRDVDNUMiKSksCiAgICB0YWJsZS5hdHRyID0gImNsYXNzPVwndGFibGUgdGFibGUtY29uZGVuc2VkXCcsIHN0eWxlPVwnd2lkdGg6MTAwJTsgZm9udC1zaXplOjkwJTtcJyIKKQpgYGAKCQkJCQoKIyMgUUMgZm9yIHRyaW1tZWQgcmVhZHMKClF1YWxpdHkgQ29udHJvbCAoUUMpIGlzIGRvbmUgZm9yIHRoZSB0cmltbWVkIHJlYWRzIHdpdGggZmFzdFFDLiAKV2UgYWN0aXZhdGUgdGhlIGNvbmRhIGVudmlyb25tZW50IGBjb25kYWZhc3RxY2AgZm9yIHRoaXMgcHJvY2Vzcy4KCmBgYAppZiAoIXJlcXVpcmUoImZhc3RxY3IiKSkgewogICAgICAgIGluc3RhbGwucGFja2FnZXMoImZhc3RxY3IiLCByZXBvcz0iaHR0cDovL2NyYW4udXMuci1wcm9qZWN0Lm9yZyIpCiAgICAgICAgbGlicmFyeShmYXN0cWNyKQp9IGVsc2Uge2xpYnJhcnkoZmFzdHFjcil9CmZhc3RxYyhmcS5kaXI9Ii9wYXRoL3RvL2RpcmVjdG9yeS90cmltbWVkX2Zhc3RxX2ZpbGVzIiwKICAgICAgcWMuZGlyPSIvcGF0aC90by9kaXJlY3RvcnkvZmFzdHFjL3RyaW1fZmFzdHFjIiwKICAgICAgdGhyZWFkcz0yMCkKYGBgCgpSdW5uaW5nIHRoZSBzY3JpcHQgd2l0aCB0aGUgZm9sbG93aW5nIGNvbW1hbmQ6CmBgYApSc2NyaXB0IGZhc3RxY3IuUgpgYGAKCiMjIyBGYXN0UUMgT3V0cHV0CgpQbG90cyBmb3IgZWFjaCBGQVNUUUMgbWV0cmljIGFmdGVyIHRyaW1taW5nIGlzIHNob3duIGJlbG93LiAKQWxsIHRoZSBhZGFwdGVycyB3ZXJlIHJlbW92ZWQgYW5kIG92ZXJhbGwgcXVhbGl0eSBsb29rcyBiZXR0ZXIuCgoqKkdlbmVyYWwgU3RhdGlzdGljcyBmcm9tIG11bHRpcWMqKgpgYGB7ciBlY2hvPUZBTFNFLCByZXN1bHRzPSdhc2lzJywgd2FybmluZz1GQUxTRX0KbGlicmFyeShyZWFkcikKbGlicmFyeShmb3JtYXR0YWJsZSkKZGZfc3RhdHMgPC0gcmVhZF90c3YoIm11bHRpcWNfdHJpbV9mYXN0cS9nZW5lcmFsX3N0YXRzX3RhYmxlLnRzdiIsIHNob3dfY29sX3R5cGVzID0gRkFMU0UpCmlzLm51bSA8LSBzYXBwbHkoZGZfc3RhdHMsIGlzLm51bWVyaWMpCmRmX3N0YXRzW2lzLm51bV0gPC0gbGFwcGx5KGRmX3N0YXRzW2lzLm51bV0sIHJvdW5kLCAxKQpmb3JtYXR0YWJsZShkZl9zdGF0cywgbGlzdCgKICAgICdQZXJjZW50RHVwcycgPSBjb2xvcl9iYXIoIiNFOTk2N0EiKSwKICAgICdQZXJjZW50R0MnID0gY29sb3JfYmFyKCIjREFBNTIwIiksCiAgICAnQlBNZWRpYW5SZWFkTGVuZ3RoJyA9IGNvbG9yX2JhcigiIzY2Q0RBQSIpLAogICAgJ01pbGxpb25zU2VxcycgPSBjb2xvcl9iYXIoIiNEQTcwRDYiKSksCiAgICB0YWJsZS5hdHRyID0gImNsYXNzPVwndGFibGUgdGFibGUtY29uZGVuc2VkXCcsIHN0eWxlPVwnd2lkdGg6ODAlOyBmb250LXNpemU6OTAlO1wnIgopCmBgYAoqKlNlcXVlbmNlIENvdW50cyBmb3IgZWFjaCBzYW1wbGUqKgoKIVtTZXF1ZW5jZSBDb3VudHNdKG11bHRpcWNfdHJpbV9mYXN0cS9tdWx0aXFjX3Bsb3RzL2Zhc3RxY19zZXF1ZW5jZV9jb3VudHNfcGxvdC5wbmcpe3dpZHRoPTU1MHB4fQoKKipUaGUgbWVhbiBxdWFsaXR5IHNjb3JlcyBwZXIgYmFzZSBpbiB0aGUgcmVhZCoqCgohW1BlciBCYXNlIFF1YWxpdHldKG11bHRpcWNfdHJpbV9mYXN0cS9tdWx0aXFjX3Bsb3RzL2Zhc3RxY19wZXJfYmFzZV9zZXF1ZW5jZV9xdWFsaXR5X3Bsb3QucG5nKXt3aWR0aD01NTBweH0KCioqVGhlIGF2ZXJhZ2UgcXVhbGl0eSBzY29yZXMgcGVyIHNlcXVlbmNlKioKCiFbUGVyIFNlcXVlbmNlIFF1YWxpdHldKG11bHRpcWNfdHJpbV9mYXN0cS9tdWx0aXFjX3Bsb3RzL2Zhc3RxY19wZXJfc2VxdWVuY2VfcXVhbGl0eV9zY29yZXNfcGxvdC5wbmcpe3dpZHRoPTU1MHB4fQoKKipUaGUgR0MgY29udGVudCBwZXIgc2VxdWVuY2UqKgoKIVtHQyBjb25ldGVudF0obXVsdGlxY190cmltX2Zhc3RxL211bHRpcWNfcGxvdHMvZmFzdHFjX3Blcl9zZXF1ZW5jZV9nY19jb250ZW50X3Bsb3QucG5nKXt3aWR0aD01NTBweH0KCgoqKlNlcXVlbmNlIER1cGxpY2F0aW9uKioKCiFbRHVwbGljYXRpb24gaW4gZWFjaCBzZXF1ZW5jZV0obXVsdGlxY190cmltX2Zhc3RxL211bHRpcWNfcGxvdHMvZmFzdHFjX3NlcXVlbmNlX2R1cGxpY2F0aW9uX2xldmVsc19wbG90LnBuZyl7d2lkdGg9NTUwcHh9CgoqKk92ZXJyZXByZXNlbnRlZCBzZXF1ZW5jZXMqKgoKIVtUb3RhbCBvdmVycmVwcmVzZW50ZWQgc2VxdWVuY2VzIGZvdW5kIGluIGVhY2ggc2FtcGxlXShtdWx0aXFjX3RyaW1fZmFzdHEvbXVsdGlxY19wbG90cy9mYXN0cWNfb3ZlcnJlcHJlc2VudGVkX3NlcXVlbmNlc19wbG90LnBuZyl7d2lkdGg9NTUwcHh9CgoqKk92ZXJhbGwgUGFzcy9GYWlsKioKCiFbQ2hlY2tpbmcgaWYgZWFjaCBzYW1wbGUgcGFzc2VzIG9yIGZhaWxzIGluIHZhcmlvdXMgbWV0ZXJpc10obXVsdGlxY190cmltX2Zhc3RxL211bHRpcWNfcGxvdHMvZmFzdHFjLXN0YXR1cy1jaGVjay1oZWF0bWFwLnBuZyl7d2lkdGg9NTUwcHh9CgoqKlNlcXVlbmNlIGxlbmd0aCBkaXN0cmlidXRpb24qKgoKIVtsZW5ndGggZGlzdHJpYnV0aW9uIG9mIHNlcXVlbmNlc10obXVsdGlxY190cmltX2Zhc3RxL211bHRpcWNfcGxvdHMvZmFzdHFjX3NlcXVlbmNlX2xlbmd0aF9kaXN0cmlidXRpb25fcGxvdC5wbmcpe3dpZHRoPTU1MHB4fQoKIyMgQWxpZ25tZW50CgpGaXJzdCB0aGluZ3MgZmlyc3QtIGNyZWF0ZSBhIGNvbmRhIGVudmlyb25tZW50IHRoYXQgaGFzIGJvd3RpZSwgc2FtdG9vbHMsIHBpY2FyZCwgYW5kIGJlZHRvb2xzLgoKYGNvbmRhIGNyZWF0ZSAtbiBjb25kYWJvd3RpZSBib3d0aWUgc2FtdG9vbHMgcGljYXJkIGJlZHRvb2xzYAoKVGhlIHRyaW1tZWQgcmVhZHMgYXJlIGFsaWduZWQgdG8gdGhlIHJlZmVyZW5jZSBnZW5vbWUgdXNpbmcgYm93dGllLgpUbyBhbmFseXplIHJlYWRzIG1hcHBpbmcgd2l0aCBtaXRvY2hvbmRyaWFsIGdlbm9tZSwgd2UgcGVyZm9ybSB0aGUgYWxpZ25tZW50IGluIHR3byBzdGVwcy4KCjEuIENvbXBsZXRlIEdlbm9tZSAod2l0aCBtaXRvY2hvbmRyaWFsIGdlbm9tZSktIHdpdGggYWxnZW5vbWUuZmEKMi4gT25seSB0aGUgTWl0b2Nob25kcmlhbCBnZW5vbWUgd2hpY2ggaXMgZXh0cmFjdGVkIGZyb20gZ2Vub21lLmZhLSBhbG1pdG9nZW5vbWUuZmEKClRvIGJlZ2luIGFsaWdubWVudCwgd2UgbWFrZSBib3d0aWUgaW5kZXhlcywgdGhpcyBpcyBkb25lIGluIHR3byBzZXRzLgoKYGBgCmJvd3RpZS1pbmRleCBhbGdlbm9tZS5mYQpib3d0aWUtaW5kZXggYWxtaXRvZ2Vub21lLmZhCmBgYAoKIyMjIEFsaWdubWVudCB3aXRoIGdlbm9tZQoKVGhlIGFsaWdubWVudCB3YXMgZG9uZSBvbiB0aGUgdHJpbW1lZCByZWFkcyBmcm9tIHByZXZpb3VzIHNlY3Rpb24uCgpgYGAKIyEvYmluL2Jhc2gKRklMRVM9Ii9kaXNrL2Jpb3NjcmF0Y2gvUG9kcmFiX2xhYi9nYXphbC9zUk5BX2dhemFsL3RyaW0vKi5mYXN0cSIKZm9yIGYgaW4gJEZJTEVTCiAgICBkbwogICAgICAgIGI9YGJhc2VuYW1lICRmYAogICAgICAgIGVjaG8gUnVubmluZyB0cmltbWluZyBmb3IgdGhlIGZpbGUgJGIKICAgICAgICB0PSR7Yjo6LTZ9CiAgICAgICAgbz0iJHQuc2FtIgogICAgICAgIHVvPSIkdC5tYXBwZWQuZnEiCiAgICAgICAgZWNobyBPdXRwdXQgZmlsZSBpcyAkbwogICAgICAgIGJvd3RpZSBcCgkgLXAgMjAgXAogICAgIAkgLXQgXAoJIC1rIDUgXAoJIC0tYmVzdCBcCgkgLS1zdHJhdGEgXAoJIC1lIDk5OTk5IFwKCSAtdiAwIFwKICAgCSAtbCAxNSBcCiAgCSAtLWNodW5rbWJzIDIwNDggXAoJIC14IC9kaXNrL2Jpb3NjcmF0Y2gvUG9kcmFiX2xhYi9nYXphbC9zUk5BX2dhemFsL2Jvd3RpZV9pbmRleF9hbGltL2FsZ2Vub21lIFwKCSAtcSAkZiBcCgkgLS1hbCAkdW8gXAoJIC0tc2FtIC0tbm8tdW5hbCA+ICRvIDI+ICR0LmJvd3RpZS5sb2cKICAgIGRvbmUKI2RvbmUKYGBgCgpUaGUgZm9sbG93aW5nIHN0YXRzIHNob3cgYWxpZ25tZW50IFFDLiAKCiFbQm93dGllIEFsaWdubWVudCBTdGF0cyB3aXRoIEdlbm9tZV0oYWxpZ25tZW50L2dlbm9tZS9ib3d0aWUxX2FsaWdubWVudC5wbmcpe3dpZHRoPTU1MHB4fQoKVGhpcyB0YWJsZSBzaG93cyB0aGUgbnVtYmVyIG9mIHJlYWRzIGFsaWduZWQgaW4gZWFjaCBzYW1wbGUgKE1pbGxpb25BbGlnbmVkUmVhZHMpLiAKSXQgYWxzbyBzaG93cyB0aGUgbnVtYmVyIG9mIGFsaWdtZW50cyBvZiB2YXJpb3VzIHJlYWRzIHRoYXQgaW5jbHVkZXMgbXVsdGltYXBwZWQgcmVhZHMgKE1pbGxpb25NYXBwZWRSZWFkcykuCgpgYGB7ciBlY2hvPUZBTFNFLCByZXN1bHRzPSdhc2lzJywgd2FybmluZz1GQUxTRX0KbGlicmFyeShyZWFkcikKbGlicmFyeShmb3JtYXR0YWJsZSkKZGZfc3RhdHMgPC0gcmVhZF90c3YoImFsaWdubWVudC9nZW5vbWUvZ2VuZXJhbF9zdGF0c190YWJsZS50c3YiLCBzaG93X2NvbF90eXBlcyA9IEZBTFNFKQppcy5udW0gPC0gc2FwcGx5KGRmX3N0YXRzLCBpcy5udW1lcmljKQpkZl9zdGF0c1tpcy5udW1dIDwtIGxhcHBseShkZl9zdGF0c1tpcy5udW1dLCByb3VuZCwgMSkKZm9ybWF0dGFibGUoZGZfc3RhdHMsIGxpc3QoCQogICAgJ1BlcmNlbnRBbGlnbmVkJyA9IGNvbG9yX2JhcigiI0IwQzRERSIpLAogICAgJ01pbGxpb25BbGlnbmVkUmVhZHMnID0gY29sb3JfYmFyKCIjRTZFNkZBIiksCiAgICAnTWlsbGlvbk1hcHBlZFJlYWRzJyA9IGNvbG9yX2JhcigiIzc3ODg5OSIpLAogICAgdGFibGUuYXR0ciA9ICJjbGFzcz1cJ3RhYmxlIHRhYmxlLWNvbmRlbnNlZFwnLCBzdHlsZT1cJ3dpZHRoOjgwJTsgZm9udC1zaXplOjkwJTtcJyIpCikKYGBgCiMjIyBBbGlnbm1lbnQgd2l0aCBtaXRvY2hvbmRyaWEKClRoZSBhbGlnbm1lbnQgd2FzIGRvbmUgb24gdGhlIHRyaW1tZWQgcmVhZHMgZnJvbSBwcmV2aW91cyBzZWN0aW9uLgoKVGhlIGZvbGxvd2luZyBzdGF0cyBzaG93IGFsaWdubWVudCBRQy4gCgpgYGAKIyEvYmluL2Jhc2gKRklMRVM9Ii9kaXNrL2Jpb3NjcmF0Y2gvUG9kcmFiX2xhYi9nYXphbC9zUk5BX2dhemFsL3RyaW0vKi5mYXN0cSIJCmZvciBmIGluICRGSUxFUwogICAgZG8KICAgICAgICBiPWBiYXNlbmFtZSAkZmAKICAgICAgICBlY2hvIFJ1bm5pbmcgYWxpZ25tZW50IGZvciB0aGUgZmlsZSAkYgogICAgICAgIHQ9JHtiOjotNn0KICAgICAgICBvPSIkdC5zYW0iCgl1bz0iJHQubWFwcGVkLmZxIgogICAgICAgIGVjaG8gT3V0cHV0IGZpbGUgaXMgJG8KICAgICAgICBib3d0aWUgXAoJIC1wIDIwIFwKICAgICAJIC10IFwKCSAtayAxMCBcCgkgLS1iZXN0IFwKCSAtLXN0cmF0YSBcCgkgLWUgOTk5OTkgXAoJIC12IDAgXAogICAJIC1sIDE1IFwKICAJIC0tY2h1bmttYnMgMjA0OCBcCgkgLXggL2Rpc2svYmlvc2NyYXRjaC9Qb2RyYWJfbGFiL2dhemFsL3NSTkFfZ2F6YWwvYm93dGllX21pdG9faW5kZXgvYWxtaXRvZ2Vub21lIFwKCSAtcSAkZiBcCgkgLS1hbCAkdW8gXAoJIC0tc2FtIC0tbm8tdW5hbCA+ICRvIDI+ICR0LmJvd3RpZS5sb2cKICAgIGRvbmUKI2RvbmUKYGBgCgohW0Jvd3RpZSBBbGlnbm1lbnQgU3RhdHMgd2l0aCBNaXRvY2hvbmRyaWFsIEdlbm9tZV0oYWxpZ25tZW50L21pdG9jaG9uZHJpYS9ib3d0aWUxX2FsaWdubWVudC5wbmcpe3dpZHRoPTU1MHB4fQoKVGhpcyB0YWJsZSBzaG93cyB0aGUgbnVtYmVyIG9mIHJlYWRzIGFsaWduZWQgaW4gZWFjaCBzYW1wbGUgKE1pbGxpb25BbGlnbmVkUmVhZHMpLiAKSXQgYWxzbyBzaG93cyB0aGUgbnVtYmVyIG9mIGFsaWdtZW50cyBvZiB2YXJpb3VzIHJlYWRzIHRoYXQgaW5jbHVkZXMgbXVsdGltYXBwZWQgcmVhZHMgKE1pbGxpb25NYXBwZWRSZWFkcykuCgpgYGB7ciBlY2hvPUZBTFNFLCByZXN1bHRzPSdhc2lzJywgd2FybmluZz1GQUxTRX0KbGlicmFyeShyZWFkcikKbGlicmFyeShmb3JtYXR0YWJsZSkKZGZfc3RhdHMgPC0gcmVhZF90c3YoImFsaWdubWVudC9taXRvY2hvbmRyaWEvZ2VuZXJhbF9zdGF0c190YWJsZS50c3YiLCBzaG93X2NvbF90eXBlcyA9IEZBTFNFKQppcy5udW0gPC0gc2FwcGx5KGRmX3N0YXRzLCBpcy5udW1lcmljKQpkZl9zdGF0c1tpcy5udW1dIDwtIGxhcHBseShkZl9zdGF0c1tpcy5udW1dLCByb3VuZCwgMikKZm9ybWF0dGFibGUoZGZfc3RhdHMsIGxpc3QoCQogICAgJ1BlcmNlbnRBbGlnbmVkJyA9IGNvbG9yX2JhcigiI0IwQzRERSIpLAogICAgJ01pbGxpb25BbGlnbmVkUmVhZHMnID0gY29sb3JfYmFyKCIjRTZFNkZBIiksCiAgICAnTWlsbGlvbk1hcHBlZFJlYWRzJyA9IGNvbG9yX2JhcigiIzc3ODg5OSIpLAogICAgdGFibGUuYXR0ciA9ICJjbGFzcz1cJ3RhYmxlIHRhYmxlLWNvbmRlbnNlZFwnLCBzdHlsZT1cJ3dpZHRoOjgwJTsgZm9udC1zaXplOjkwJTtcJyIpCikKYGBgCkFub3RoZXIgUUMgdGhhdCB3ZSBjb3VsZCBmbyB3aXRoIHRoZSBhbGlnbmVkIHJlYWQgaXMgd2l0aCBQaWNhcmQuIFRoZSBmb2xsb3dpbmcgaXMgdGhlIGNvbW1hbmQgbGluZSB0byBkbyB0aGF0OgoKYGBgCkZJTEVTPSIvZGlzay9iaW9zY3JhdGNoL1BvZHJhYl9sYWIvZ2F6YWwvc1JOQV9nYXphbC9hbGlnbl93aXRoX2FsaW1fZm9yX2Fubm8vYWxpbV9taXRvX2Fubm8vKnNvcnRlZC5iYW0iCmZvciBmIGluICRGSUxFUwogICAgZG8KICAgICAgICBiPWBiYXNlbmFtZSAkZmAKICAgICAgICBlY2hvIENvbnZlcnRpbmcgZmlsZSAkYgogICAgICAgIG89IiRiLnBpY2FyZC50eHQiCiAgICAgICAgZWNobyBPdXRwdXQgZmlsZSBpcyAkbwoJcGljYXJkIC1YbXg1ZyBDb2xsZWN0QWxpZ25tZW50U3VtbWFyeU1ldHJpY3MgST0kZiBPPSRvIFI9L2Rpc2svYmlvc2NyYXRjaC9Qb2RyYWJfbGFiL2dhemFsL3NSTkFfZ2F6YWwvY29waWVkX29sZF9pbmZpbGVzL0dDRl8wMDEyNjY3NzUuMV9BdXN0cm9mdW5kdWx1c19saW1uYWV1cy0xLjBfZ2Vub21pY19hbmRNSVRPLmZuYQogICAgZG9uZQojZG9uZQoKYGBgCgpCZWZvcmUgd2UgcHJvY2VlZCwgd2UgbmVlZCB0byBzb3J0IHRoZSBzYW0sIGNvbnZlcnQgaXQgaW50byBiYW0gYW5kIGNyZWF0ZSBhIGJhbSBpbmRleCAoYmFpKS4KVGhpcyBzdGVwIGVuc3VyZXMgdGhhdCB3ZSBjb3VsZCBzdG9yZSB0aGUgYWxpZ25tZW50cyBpbiBhY2NlcHRhYmxlIGJpbmFyeSBmb3JtYXQgdGhhdCB0YWtlcyBsZXNzIHN0b3JhZ2Ugc3BhY2UKYW5kIGlzIGNvbXBhdGlibGUgd2l0aCBzdWJzZXF1ZW50IHN0ZXBzLgoKCmBgYApGSUxFUz0iL2Rpc2svYmlvc2NyYXRjaC9Qb2RyYWJfbGFiL2dhemFsL3NSTkFfZ2F6YWwvYWxpZ25fd2l0aF9hbGltX2Zvcl9hbm5vL2FsaW1fbWl0b19hbm5vLyouc2FtIgpmb3IgZiBpbiAkRklMRVMKICAgIGRvCiAgICAgICAgYj1gYmFzZW5hbWUgJGZgCiAgICAgICAgZWNobyBDb252ZXJ0aW5nICRiIHRvIGJhbQogICAgICAgIG89JHtiOjotNH0KICAgICAgICBiYW09IiRvLmJhbSIKCXNvcnRlZGJhbT0iJGIuc29ydGVkLmJhbSIKCQoJZWNobyBUbXAgZmlsZSBpcyAkYmFtCiAgICAgICAgc2FtdG9vbHMgdmlldyAtYiAkZiA+ICRiYW0KCQogICAgICAgIGVjaG8gT3V0cHV0IGZpbGVzIGFyZSAkc29ydGVkYmFtIGFuZCBpdHMgaW5kZXgKCXNhbXRvb2xzIHNvcnQgJGJhbSAtbyAkc29ydGVkYmFtCglzYW10b29scyBpbmRleCAkc29ydGVkYmFtCgllY2hvIERlbGV0aW5nIFRtcCBmaWxlICRiYW0gCglybSAkYmFtIAogICAgZG9uZQojZG9uZQpgYGAKCiMjIFVzaW5nIGFsaWduZWQgcmVhZHMKCldlIHdpbGwgY3JlYXRlIHRocmVlIGZpbGVzOgoKMS4gU3VtbWFyeSBpbmZvcm1hdGlvbiB0aGF0IGhhcyByZWFkIElELCBzZXF1ZW5jZSwgcmVmZXJlbmNlIGxvY2F0aW9uLCBhbmQgbnVtYmVyIG9mIGFsaWdubWVudHMuCjIuIEV4YWN0IGxvY2F0aW9uLCBnZW5vbWljIGZlYXR1cmVzIG9mIHRoZSByZWZlcmVuY2UgbG9jYXRpb24gdGhhdCB0aGUgcmVhZHMgbWFwcGVkIHRvIHZpYSBiZWR0b29scy4KMy4gQ291bnRpbmcgdGhlIHJlYWRjb3VudHMgZnJvbSBiYW0gZmlsZXMuCgpgYGAjIS9iaW4vYmFzaApGSUxFUz0iL2Rpc2svYmlvc2NyYXRjaC9Qb2RyYWJfbGFiL2dhemFsL3NSTkFfZ2F6YWwvYWxpZ25fd2l0aF9hbGltX2Zvcl9hbm5vL2FsaW1fbWl0b19hbm5vLyouYmFtIgpmb3IgZiBpbiAkRklMRVMKICAgIGRvCiAgICAgICAgYj1gYmFzZW5hbWUgJGZgCiAgICAgICAgZWNobyAkYgogICAgICAgIG89JHtiOjotNH0KICAgICAgICBvPSIkby5zdW1tYXJ5LnR4dCIKCWlucHV0X2ZpbGU9IiRmIgoJb3V0cHV0X2ZpbGU9IiRvLnN1bW1hcnkudHh0IgoKCSMgUHJvY2VzcyB0aGUgaW5wdXQgZmlsZSB3aXRoIHNhbXRvb2xzIGFuZCBhd2sKCXNhbXRvb2xzIHZpZXcgJGYgfCBhd2sgJ3twcmludCAkMSwgJDEwLCAkMywgJDQsICQxNX0nIHwgc29ydCB8IHVuaXEgPiAiJG91dHB1dF9maWxlIgoJZWNobyAiT3V0cHV0IGZpbGUgd3JpdHRlbiAkb3V0cHV0X2ZpbGUiCiAgICBkb25lCmBgYApUaGUgcmVzdWx0IGlzIHRoZSBmb2xsb3dpbmcgZGF0YSBmb3IgZWFjaCBmaWxlLiBUaGUgc2FtcGxlIDFfMTJkX3QwIGlzIHNob3duLgohW10oc2NyZWVucy9zdW1tYXJ5XzFfMTJkX3QwLnBuZykKCmBgYCMhL2Jpbi9iYXNoCkZJTEVTPSIvZGlzay9iaW9zY3JhdGNoL1BvZHJhYl9sYWIvZ2F6YWwvc1JOQV9nYXphbC9hbGlnbl93aXRoX2FsaW1fZm9yX2Fubm8vYWxpbV9taXRvX2Fubm8vKi5iYW0iCmZvciBmIGluICRGSUxFUwogICAgZG8KICAgICAgICBiPWBiYXNlbmFtZSAkZmAKICAgICAgICBlY2hvICRiCiAgICAgICAgbz0ke2I6Oi00fQogICAgICAgIGJlZD0iJG8uYmVkIgoJb3V0PSIkby5iZWR0b29scy50eHQiCglnZmY9Ii9kaXNrL2Jpb3NjcmF0Y2gvUG9kcmFiX2xhYi9nYXphbC9zUk5BX2dhemFsL21pdG9fZ2Vub21lL0dDRl8wMDEyNjY3NzUuMV9BdXN0cm9mdW5kdWx1c19saW1uYWV1c19NSVRPb25seS5nZmYiCgliZWR0b29scyBpbnRlcnNlY3QgLWEgJGYgLWIgJGdmZiAtd28gLWYgMSAtYmVkID4gJGJlZAoJYXdrICchc2VlblskNF0rKycgJGJlZCA+IHRtcC5jc3YKCXJtICRiZWQKCWF3ayAne3ByaW50ICQ0LCAkMjF9JyB0bXAuY3N2ID4gJG91dAoJcm0gdG1wLmNzdgoJZWNobyAiT3V0cHV0IGZpbGUgd3JpdHRlbiAkb3V0IgogICAgZG9uZQoKYGBgClRoZSByZXN1bHQgb2YgYWJvdmUgY29tbWFuZCBnaXZlcyB1cyB0aGUgZm9sbG93aW5nIGRhdGEgZm9yIGVhY2ggZmlsZS4gVGhlIHNhbXBsZSAxXzEyZF90MCBpcyBzaG93bi4KIVtdKHNjcmVlbnMvYmVkdG9vbHNfMV8xMmRfdDAucG5nKQoKCmBgYCMhL2Jpbi9iYXNoCkZJTEVTPSIvZGlzay9iaW9zY3JhdGNoL1BvZHJhYl9sYWIvZ2F6YWwvc1JOQV9nYXphbC9hbGlnbl93aXRoX2FsaW1fZm9yX2Fubm8vYWxpbV9taXRvX2Fubm8vKi5iYW0iCmZvciBmIGluICRGSUxFUwogICAgZG8KICAgICAgICBiPWBiYXNlbmFtZSAkZmAKICAgICAgICBlY2hvICRiCiAgICAgICAgbz0ke2I6Oi00fQogICAgICAgIG89IiRvLnJlYWRjb3VudC50eHQiCiAgICAgICAgZWNobyBPdXRwdXQgZmlsZSBpcyAkbwoJIyBDb3VudCB1bmlxdWUgb2NjdXJyZW5jZXMgb2YgY29sdW1uIDEwCglzYW10b29scyB2aWV3ICRmIHwgYXdrICd7cHJpbnQgJDEwfSd8IHNvcnQgfCB1bmlxIC1jID4gIiRvIgoJZWNobyAiT3V0cHV0IHdyaXR0ZW4gdG8gJG8iCiAgICBkb25lCgpgYGAKVGhlIHJlc3VsdCBvZiBhYm92ZSBjb21tYW5kIGdpdmVzIHVzIHRoZSBmb2xsb3dpbmcgZGF0YSBmb3IgZWFjaCBmaWxlLiBUaGUgc2FtcGxlIDFfMTJkX3QwIGlzIHNob3duLgohW10oc2NyZWVucy9yZWFkY291bnRfMV8xMmRfdDAucG5nKQoKIyMjIG1pUlRyYWNlCiBSdW5uaW5nIG1pcnRyYWNlIHdpdGggdGhlIGZvbGxvd2luZyBjb21tYW5kLgoKYGBgIyEvYmluL2Jhc2gKbWlydHJhY2UgcWMgLS1zcGVjaWVzIGRyZSAtLWNvbmZpZyBzZXFfYWRkcmVzcy50eHQKYGBgCgpMb29raW5nIGF0IHRoZSByZXN1bHRzOgoKIVtdKG1pcnRyYWNlL21pcnRyYWNlLWxlbmd0aC1wbG90LnBuZyl7d2lkdGg9MTAwJX0KIVtdKG1pcnRyYWNlL21pcnRyYWNlLXJuYXR5cGUtcGxvdC5wbmcpe3dpZHRoPTEwMCV9CgojIyMgc3BvcnRzCgpFeGVjdXRpbmcgc3BvcnRzIHRvb2wgb24gbWFwcGVkIHJlYWRzIG9ubHkuIFdlIHVzZSB0aGUgZm9sbG93aW5nIGNvbW1hbmQgdG8gcnVuOgoKYGBgCiMhL2Jpbi9iYXNoCnNwb3J0cy5wbCAtaSBzZXFzX2FsaW1fbWl0by50eHQgXAotbyAvZGlzay9iaW9zY3JhdGNoL1BvZHJhYl9sYWIvZ2F6YWwvc1JOQV9nYXphbC9hbGlnbl93aXRoX2FsaW1uYWV1cy9nZW5faW5wdXRfZmFzdHEvU1BPUlRTL291dF9zcG9ydHMvUkVETy9taXRvX21hcHBlZF9yZWFkcyBcCi1rIFwKLU0gMiBcCi1wIDIwIFwKLWcgL2Rpc2svYmlvc2NyYXRjaC9Qb2RyYWJfbGFiL2dhemFsL3NSTkFfZ2F6YWwvYm93dGllX21pdG9faW5kZXgvYWxtaXRvZ2Vub21lIFwKLW0gL2Rpc2svYmlvc2NyYXRjaC9Qb2RyYWJfbGFiL2dhemFsL3NSTkFfZ2F6YWwvYWxpZ25fd2l0aF9hbGltbmFldXMvZ2VuX2lucHV0X2Zhc3RxL1NQT1JUUy9zcG9ydHMxLjEvZGIvRGFuaW9fcmVyaW8vbWlSQmFzZV8yMS9taVJCYXNlXzIxLWRyZSBcCi1yIC9kaXNrL2Jpb3NjcmF0Y2gvUG9kcmFiX2xhYi9nYXphbC9zUk5BX2dhemFsL2FsaWduX3dpdGhfYWxpbW5hZXVzL2dlbl9pbnB1dF9mYXN0cS9TUE9SVFMvc3BvcnRzMS4xL2RiL0RhbmlvX3JlcmlvL3JSTkFfZGIvemVicmFmaXNoX3JSTkEgXAotdCAvZGlzay9iaW9zY3JhdGNoL1BvZHJhYl9sYWIvZ2F6YWwvc1JOQV9nYXphbC9hbGlnbl93aXRoX2FsaW1uYWV1cy9nZW5faW5wdXRfZmFzdHEvU1BPUlRTL3Nwb3J0czEuMS9kYi9EYW5pb19yZXJpby9HdFJOQWRiL2RhblJlcjYtdFJOQXMgXAotdyAvZGlzay9iaW9zY3JhdGNoL1BvZHJhYl9sYWIvZ2F6YWwvc1JOQV9nYXphbC9hbGlnbl93aXRoX2FsaW1uYWV1cy9nZW5faW5wdXRfZmFzdHEvU1BPUlRTL3Nwb3J0czEuMS9kYi9EYW5pb19yZXJpby9waVJCYXNlL3BpUl9kcmVfdjEuMCBcCi1lIC9kaXNrL2Jpb3NjcmF0Y2gvUG9kcmFiX2xhYi9nYXphbC9zUk5BX2dhemFsL2FsaWduX3dpdGhfYWxpbW5hZXVzL2dlbl9pbnB1dF9mYXN0cS9TUE9SVFMvc3BvcnRzMS4xL2RiL0RhbmlvX3JlcmlvL0Vuc2VtYmwvRGFuaW9fcmVyaW8uR1JDejEwLm5jcm5hIFwKLWYgL2Rpc2svYmlvc2NyYXRjaC9Qb2RyYWJfbGFiL2dhemFsL3NSTkFfZ2F6YWwvYWxpZ25fd2l0aF9hbGltbmFldXMvZ2VuX2lucHV0X2Zhc3RxL1NQT1JUUy9zcG9ydHMxLjEvZGIvRGFuaW9fcmVyaW8vUmZhbV8xMi4zL1JmYW0tMTIuMy16ZWJyYWZpc2gKYGBgCgpUaGlzIHdpbGwgZ2VuZXJhdGUgYSBudW1iZXIgb2Ygb3V0cHV0IGZpbGVzLCBmcm9tIHdoaWNoIHRoZSB0YWJsZXMKZ2VuZXJhdGVkIGFzIGEgcmVzdWx0IGZpbGUgKl9vdXRwdXQudHh0IGZvciBlYWNoIHNhbXBsZSBhcmUgdGFrZW4gYW5kIAphcmUgdXNlZCB0byBleHRyYWN0IGFubm90YXRpb24gb2YgbWFwcGVkIHJlYWRzLgpUb3AgNTAgcm93cyBvZiB0aGlzIHRhYmxlIGFyZSBzaG93biBmb3IgdGhlIHNhbXBsZSAxMF8xMmRfNGhyQSBiZWxvdy4gCgoKIVtdKHNwb3J0cy9TY3JlZW5zaG90ZnJvbTEwXzEyZF80aHJBLnBuZyl7d2lkdGg9NTUwcHh9CgpJdCBhbHNvIGdlbmVyYXRlcyBhIG51bWJlciBvZiBwbG90cyB0byBjYXRlZ29yaXplIHRoZSBhbm5vdGF0aW9ucyAKYW5kIHRoZWlyIGxlbmd0aCBkaXN0cmlidXRpb25zIGZvciBlYWNoIHNhbXBsZS4KCiFbXShzcG9ydHMvU2NyZWVuc2hvdDEwXzEyZF80aHJBLnBuZyl7d2lkdGg9NTUwcHh9CiFbXShzcG9ydHMvU2NyZWVuc2hvdDEwXzEyZF80aHJBX2dyYXBoLnBuZyl7d2lkdGg9NTUwcHh9CgojIyBDb21waWxpbmcgb3V0cHV0IGZpbGVzCgpBdCB0aGUgZW5kLCB3ZSBuZWVkIHRvIGNvbXBpbGUgYWxsIHRoZSBvdXRwdXQgZmlsZXMgaW50byBhIHNpbmdsZSBkYXRhZnJhbWUgdGhhdCBjYW4gYmUgZXhwb3J0ZWQKdG8gZnVydGhlciBkbyBkb3duc3RyZWFtIHByb2Nlc3Npbmcgc3VjaCBhcyBzdGF0aXN0aWNzLCBkaWZmZXJlbnRpYWwgZXhwcmVzc2lvbiwgYW5kIGNsdXN0ZXJpbmcuCgpXZSBwcm92aWRlIGFuIFtSIHNjcmlwdF0oc2NyaXB0cy9tZXJnZV9jb3VudHNfbWl0by5SKSB0aGF0IGNvbXBpbGVzIHRoZXNlIG91dHB1dCBmaWxlczoKCjEuIEFubm90YXRpb246IEZyb20gKipzcG9ydHMqKi0gKi5tYXBwZWRfb3V0cHV0LnR4dAoyLiBBbGlnbm1lbnQgc3VtbWFyeTogRnJvbSAuYmFtIGZpbGVzIHdpdGggKipzYW10b29scyoqLSAqLnN1bW1hcnkudHh0CjMuIFJlYWRjb3VudDogRnJvbSAuYmFtIGZpbGVzIHdpdGggKipzYW10b29scyoqIGFuZCAqKmF3ayoqLSAqLnJlYWRjb3VudC50eHQKNC4gTG9jYXRpb246IEZyb20gLmJhbSBmaWxlcyB3aXRoICoqYmVkdG9vbHMqKi0gKi5iZWR0b29scy50eHQKCkluIGFkZGl0aW9uLCB3ZSBhbHNvIG5lZWQgYSBzYW1wbGUgZGVzaWduIGZpbGUgKC5jc3YgZm9ybWF0KSB0aGF0IGhhcyBkZXRhaWxzIGFib3V0IHRoZSBzYW1wbGVzLgpUaGlzIGZpbGUgbWFrZXMgaXQgZWFzaWVyIHRvIGRvIHN0YXRpc3RpY2FsIGFuYWx5c2lzIG9uIHRoZSBkYXRhIHVzaW5nIFIgcGFja2FnZXMgbGlrZSAKREVTZXEyLCBFeHByZXNzaW9uU2V0LCBhbmQgRWRnZVIuCgpZb3Ugd291bGQgYWx0ZXIgdGhlIGZvbGxvd2luZyBsaW5lcyBpbiB0aGUgUiBzY3JpcHQgdGhhdCBiYXNpY2FsbHkgdGVsbHMgdGhlIHByb2dyYW0gd2hlcmUgdGhlc2UgdHh0IGZpbGVzIGFyZSBsb2NhdGVkLgoKYGBge3IsIGV2YWw9RkFMU0V9CnBhcmVudF9kaXIgPC0gIkQ6L1BTVV93b3JrL3Ntcm5hc2VxL21pdG9fbWFwIgpzYW1wbGVzIDwtICJEOi9QU1Vfd29yay9zbXJuYXNlcS9taXRvX21hcC9kZXNpZ25fc2FtcGxlcy5jc3YiCnJlYWRjb3VudF90eHRfcGF0dGVybiA8LSAic29ydGVkLnJlYWRjb3VudC50eHQkIgpvdXRwdXRfdHh0X3BhdHRlcm4gPC0gIm1hcHBlZF9vdXRwdXQudHh0JCIKc3VtbWFyeV90eHRfcGF0dGVybiA8LSAic3VtbWFyeS50eHQkIgpiZWR0b29sc190eHRfcGF0dGVybiA8LSAiYmVkdG9vbHMudHh0JCIKYGBgCgpTZXQgcGF0dGVybiBvZiBmaWxlbmFtZXM6IHRoZXNlIGZpbGVzIGFyZSBzZWFyY2hlZCBpbiB0aGUgcGFyZW50X2RpciByZWN1cnNpdmVseS4KTWFrZSBzdXJlIHRoYXQgdGhlIHBhcmVudF9kaXIgY29udGFpbnMgdGhlc2UgZmlsZXMgYW5kIHRoZSBwYXR0ZXJuIHNob3VsZCBiZSB1bmlxdWUgdG8gbGlzdCB0aGUgZmlsZXMgdGhhdCB3ZSBuZWVkLgoKTWVyZ2UgcmVzdWx0cyBmcm9tIG91ciBzYW1wbGVzIGNhbiBiZSB2aWV3ZWQgZnJvbSBvdXIgW2dpdGh1YiByZXBvXShodHRwczovL2dpdGh1Yi5jb20vSnBvZC1sYWIvc3JuYWRvY3MvdHJlZS9tYWluKQoKIyMgVmlzdWFsaXppbmcKV2UgdXNlIHRoZSBhbGlnbm1lbnRzIHdpdGggbWl0b2Nob25kcmlhbCBnZW5vbWUgdG8gdmlldyB0aGUgYWxpZ25lZCByZWFkcy4KCkpicm93c2UgaXMgdXNlZCB0byBleHBsb3JlIGFsaWdubWVudHMuCgpGaWxlcyB1c2VkOgoKMS4gQWxpZ25lZCBiYW0gZmlsZXMgZm9yIGVhY2ggc2FtcGxlIGFuZCBpdHMgY29ycmVzcG9uZGluZyBpbmRleCBmaWxlIChiYW0sIGJhaSkKMy4gUmVmZXJlbmNlIGdlbm9tZSBmb3IgbWl0b2Nob25kcmlhICguZmFzdGEpIGFuZCBpdHMgaW5kZXggZmlsZSAoLmZhaSkKNC4gR2Vub21lIGZlYXR1cmUgZmlsZSAoLmdmZikgZm9yIG1pdG9jaG9uZHJpYWwgZ2Vub21lCgohW10oamJyb3dzZS9qYnJvd3NlXzRkX3QwLnN2ZykKPGEgaHJlZj0iamJyb3dzZS9qYnJvd3NlXzRkX3QwLnN2ZyIgdGFyZ2V0PSJfYmxhbmsiPiBDbGljayB0byBlbmxhcmdlPC9hPgoKVGhpcyBmaWd1cmUgc2hvd3MgbWl0b2Nob25kaXJhbCBnZW5vbWUgb2YgMTAwYnAgbGVuZ3RoIGZyb20gMTcxMDAgdG8gMTcxOTkuIE9uIHRoaXMgZ2Vub21lLCB3ZSBzZWUgCjEpIHRoZSBjb2xvcmVkIGJhc2VwYWlycywgMikgR2Vub21pYyBmZWF0dXJlcyBvZiB0aGUgbWVudGlvbmVkIGxlbmd0aCwgMykgQWxpZ25tZW50cyBmcm9tIDQgc2FtcGxlcyAoNGQgdDAgcmVwbGljYXRlcykKdGhhdCBzaG93IHJlYWRzIGFsaWduZWQgdG8gdGhlIGdlbm9tZSBjb2xvcmVkIGJ5IHN0cmFuZCB3aGlsZSBhbHNvIHNob3dpbmcgdGhlIGNvdmVyYWdlIGhpc3RvZ3JhbSBpbiBncmV5LiA=